{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "大家好，我是『K同学啊』！\n",
    "\n",
    "接着上一篇文章 [深度学习100例 | 第24天-卷积神经网络（Xception）：动物识别](https://mtyjkh.blog.csdn.net/article/details/120073717)，我用Xception模型实现了对狗、猫、鸡、马等四种动物的识别，带大家了解了Xception的构建。这次我们来 **实现一下中文版的 [手写数字识别](https://mtyjkh.blog.csdn.net/article/details/116920825)** ，听到手写数字识别或许会觉得简单，今天可能不一定哈。\n",
    "\n",
    "本次的重点：\n",
    "- 数据检查：在开始之前做一系列检查避免后期由于数据原因出现的bug。\n",
    "- 各项指标评估部分"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "🔥本文 GitHub [https://github.com/kzbkzb/Python-AI](https://github.com/kzbkzb/Python-AI) 已收录\n",
    "\n",
    "- 作者：[K同学啊](https://mp.weixin.qq.com/s/NES9RhtAhbX_jsmGua28dA)\n",
    "- 来自专栏：《深度学习100例》-Tensorflow2版本\n",
    "- 数据链接：https://pan.baidu.com/s/1XRhJJ23CDSoVlzHhfYGSYQ （提取码：0gnh）\n",
    "\n",
    "🚀我的环境：\n",
    "\n",
    "- 语言环境：Python3.6.5\n",
    "- 编译器：jupyter notebook\n",
    "- 深度学习环境：TensorFlow2.4.1\n",
    "- 显卡（GPU）：NVIDIA GeForce RTX 3080\n",
    "\n",
    "**🚀 来自专栏：[《深度学习100例》](https://blog.csdn.net/qq_38251616/category_11068756.html)**\n",
    "\n",
    "**如果你是一名深度学习小白可以先看看我这个专门为你写的专栏：[《小白入门深度学习》](https://blog.csdn.net/qq_38251616/category_11188161.html)**\n",
    "\n",
    "1. [小白入门深度学习 | 第一篇：配置深度学习环境](https://mtyjkh.blog.csdn.net/article/details/118575238)\n",
    "2. [小白入门深度学习 | 第二篇：编译器的使用-Jupyter Notebook](https://mtyjkh.blog.csdn.net/article/details/118814364)\n",
    "3. [小白入门深度学习 | 第三篇：深度学习初体验](https://mtyjkh.blog.csdn.net/article/details/119081309)\n",
    "4. [小白入门深度学习 | 第四篇：配置PyTorch环境](https://mtyjkh.blog.csdn.net/article/details/119969393)\n",
    "\n",
    "🚀 往期精彩-卷积神经网络篇：\n",
    "\n",
    "1. [深度学习100例-卷积神经网络（CNN）实现mnist手写数字识别 | 第1天](https://mtyjkh.blog.csdn.net/article/details/116920825) \n",
    "2. [深度学习100例-卷积神经网络（CNN）彩色图片分类 | 第2天](https://mtyjkh.blog.csdn.net/article/details/116978213)\n",
    "3. [深度学习100例-卷积神经网络（CNN）服装图像分类 | 第3天](https://mtyjkh.blog.csdn.net/article/details/116992196)\n",
    "4. [深度学习100例-卷积神经网络（CNN）花朵识别 | 第4天](https://mtyjkh.blog.csdn.net/article/details/117079919)\n",
    "5. [深度学习100例-卷积神经网络（CNN）天气识别 | 第5天](https://mtyjkh.blog.csdn.net/article/details/117186183)\n",
    "6. [深度学习100例-卷积神经网络（VGG-16）识别海贼王草帽一伙 | 第6天](https://mtyjkh.blog.csdn.net/article/details/117331631)\n",
    "7. [深度学习100例-卷积神经网络（VGG-19）识别灵笼中的人物 | 第7天](https://mtyjkh.blog.csdn.net/article/details/117395797)\n",
    "8. [深度学习100例-卷积神经网络（ResNet-50）鸟类识别 | 第8天](https://mtyjkh.blog.csdn.net/article/details/117587326)\n",
    "9. [深度学习100例-卷积神经网络（AlexNet）手把手教学 | 第11天](https://mtyjkh.blog.csdn.net/article/details/117986183)\n",
    "10. [深度学习100例-卷积神经网络（CNN）识别验证码 | 第12天](https://mtyjkh.blog.csdn.net/article/details/118211253)\n",
    "11. [深度学习100例-卷积神经网络（Inception V3）识别手语 | 第13天](https://mtyjkh.blog.csdn.net/article/details/118310170)\n",
    "12. [深度学习100例-卷积神经网络（Inception-ResNet-v2）识别交通标志 | 第14天](https://mtyjkh.blog.csdn.net/article/details/118389790)\n",
    "13. [深度学习100例-卷积神经网络（CNN）实现车牌识别 | 第15天](https://mtyjkh.blog.csdn.net/article/details/118422302)\n",
    "14. [深度学习100例-卷积神经网络（CNN）识别神奇宝贝小智一伙 | 第16天](https://mtyjkh.blog.csdn.net/article/details/118631541)\n",
    "15. [深度学习100例-卷积神经网络（CNN）注意力检测 | 第17天](https://mtyjkh.blog.csdn.net/article/details/118938811)\n",
    "16. [深度学习100例-卷积神经网络（VGG-16）猫狗识别 | 第21天](https://mtyjkh.blog.csdn.net/article/details/119531838)\n",
    "17. [深度学习100例-卷积神经网络（LeNet-5）深度学习里的“Hello Word” | 第22天](https://mtyjkh.blog.csdn.net/article/details/119700804)\n",
    "18. [深度学习100例-卷积神经网络（CNN）3D医疗影像识别 | 第23天](https://mtyjkh.blog.csdn.net/article/details/119899570)\n",
    "19. [深度学习100例 | 第24天-卷积神经网络（Xception）：动物识别](https://blog.csdn.net/qq_38251616/article/details/120073717)\n",
    "\n",
    "🚀 往期精彩-循环神经网络篇：\n",
    "\n",
    "1. [深度学习100例-循环神经网络（RNN）实现股票预测 | 第9天](https://mtyjkh.blog.csdn.net/article/details/117752046)\n",
    "2. [深度学习100例-循环神经网络（LSTM）实现股票预测 | 第10天](https://mtyjkh.blog.csdn.net/article/details/117907074)\n",
    "\n",
    "🚀 往期精彩-生成对抗网络篇：\n",
    "\n",
    "1. [深度学习100例-生成对抗网络（GAN）手写数字生成 | 第18天](https://mtyjkh.blog.csdn.net/article/details/118995896)\n",
    "2. [深度学习100例-生成对抗网络（DCGAN）手写数字生成 | 第19天](https://mtyjkh.blog.csdn.net/article/details/119133575)\n",
    "3. [深度学习100例-生成对抗网络（DCGAN）生成动漫小姐姐 | 第20天](https://mtyjkh.blog.csdn.net/article/details/119182578)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# 一、设置GPU"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "gpus = tf.config.list_physical_devices(\"GPU\")\n",
    "\n",
    "if gpus:\n",
    "    gpu0 = gpus[0] #如果有多个GPU，仅使用第0个GPU\n",
    "    tf.config.experimental.set_memory_growth(gpu0, True) #设置GPU显存用量按需使用\n",
    "    tf.config.set_visible_devices([gpu0],\"GPU\")\n",
    "    \n",
    "import matplotlib.pyplot as plt\n",
    "import os,PIL,pathlib\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import warnings\n",
    "from tensorflow import keras\n",
    "\n",
    "warnings.filterwarnings(\"ignore\")#忽略警告信息\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签\n",
    "plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号\n",
    "os.environ['TF_CPP_MIN_LOG_LEVEL']='2'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# 二、导入数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "IMAGE_WIDTH = 64\n",
    "IMAGE_HEIGHT = 64\n",
    "IMAGE_CHANNELS = 1\n",
    "RANDOM_STATE = 42\n",
    "TEST_SIZE = 0.2\n",
    "VAL_SIZE = 0.2\n",
    "BATCH_SIZE = 32\n",
    "NO_EPOCHS = 50\n",
    "PATIENCE = 5\n",
    "VERBOSE = 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. pandas导入数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>suite_id</th>\n",
       "      <th>sample_id</th>\n",
       "      <th>code</th>\n",
       "      <th>value</th>\n",
       "      <th>character</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>7606</th>\n",
       "      <td>63</td>\n",
       "      <td>6</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>一</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>223</th>\n",
       "      <td>29</td>\n",
       "      <td>3</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>九</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>852</th>\n",
       "      <td>86</td>\n",
       "      <td>2</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>九</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2408</th>\n",
       "      <td>45</td>\n",
       "      <td>8</td>\n",
       "      <td>12</td>\n",
       "      <td>100</td>\n",
       "      <td>百</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6743</th>\n",
       "      <td>76</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>零</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      suite_id  sample_id  code  value character\n",
       "7606        63          6     2      1         一\n",
       "223         29          3    10      9         九\n",
       "852         86          2    10      9         九\n",
       "2408        45          8    12    100         百\n",
       "6743        76          3     1      0         零"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df = pd.read_csv(\"./data/chinese_mnist.csv\")\n",
    "\n",
    "data_df.sample(100).head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "## 2. 检查数据是否缺失"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Total</th>\n",
       "      <th>Percent</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>character</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>value</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>code</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sample_id</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>suite_id</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           Total  Percent\n",
       "character      0      0.0\n",
       "value          0      0.0\n",
       "code           0      0.0\n",
       "sample_id      0      0.0\n",
       "suite_id       0      0.0"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 查看是否有缺失数据\n",
    "def missing_data(data):\n",
    "    total = data.isnull().sum().sort_values(ascending = False)\n",
    "    percent = (data.isnull().sum()/data.isnull().count()*100).sort_values(ascending = False)\n",
    "    return pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])\n",
    "missing_data(data_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**（1）打印数据总量**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据总量: 15000\n"
     ]
    }
   ],
   "source": [
    "IMAGE_PATH = './data/pictures/'\n",
    "image_files = list(os.listdir(IMAGE_PATH))\n",
    "print(\"数据总量: {}\".format(len(image_files)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**（2）匹配到的数据总量**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "匹配到的数据总量: 15000\n"
     ]
    }
   ],
   "source": [
    "def create_file_name(x):\n",
    "    file_name = f\"input_{x[0]}_{x[1]}_{x[2]}.jpg\"\n",
    "    return file_name\n",
    "\n",
    "data_df[\"file\"] = data_df.apply(create_file_name, axis=1)\n",
    "\n",
    "file_names = list(data_df['file'])\n",
    "print(\"匹配到的数据总量: {}\".format(len(set(file_names).intersection(image_files))))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**（3）检查数据的各项信息**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def read_image_sizes(file_name):\n",
    "    image = skimage.io.imread(IMAGE_PATH + file_name)\n",
    "    return list(image.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>suite_id</th>\n",
       "      <th>sample_id</th>\n",
       "      <th>code</th>\n",
       "      <th>value</th>\n",
       "      <th>character</th>\n",
       "      <th>file</th>\n",
       "      <th>w</th>\n",
       "      <th>h</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>九</td>\n",
       "      <td>input_1_1_10.jpg</td>\n",
       "      <td>64</td>\n",
       "      <td>64</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>10</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>九</td>\n",
       "      <td>input_1_10_10.jpg</td>\n",
       "      <td>64</td>\n",
       "      <td>64</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>九</td>\n",
       "      <td>input_1_2_10.jpg</td>\n",
       "      <td>64</td>\n",
       "      <td>64</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>九</td>\n",
       "      <td>input_1_3_10.jpg</td>\n",
       "      <td>64</td>\n",
       "      <td>64</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>10</td>\n",
       "      <td>9</td>\n",
       "      <td>九</td>\n",
       "      <td>input_1_4_10.jpg</td>\n",
       "      <td>64</td>\n",
       "      <td>64</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   suite_id  sample_id  code  value character               file   w   h\n",
       "0         1          1    10      9         九   input_1_1_10.jpg  64  64\n",
       "1         1         10    10      9         九  input_1_10_10.jpg  64  64\n",
       "2         1          2    10      9         九   input_1_2_10.jpg  64  64\n",
       "3         1          3    10      9         九   input_1_3_10.jpg  64  64\n",
       "4         1          4    10      9         九   input_1_4_10.jpg  64  64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import skimage\n",
    "import skimage.io\n",
    "import skimage.transform\n",
    "m = np.stack(data_df['file'].apply(read_image_sizes))\n",
    "\n",
    "df = pd.DataFrame(m,columns=['w','h'])\n",
    "data_df = pd.concat([data_df,df],axis=1, sort=False)\n",
    "data_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 划分数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "train_df, test_df = train_test_split(data_df, test_size=TEST_SIZE, random_state=RANDOM_STATE, stratify=data_df[\"code\"].values)\n",
    "train_df, val_df  = train_test_split(train_df, test_size=VAL_SIZE, random_state=RANDOM_STATE, stratify=train_df[\"code\"].values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train set rows: 9600\n",
      "Test  set rows: 3000\n",
      "Val   set rows: 2400\n"
     ]
    }
   ],
   "source": [
    "print(\"Train set rows: {}\".format(train_df.shape[0]))\n",
    "print(\"Test  set rows: {}\".format(test_df.shape[0]))\n",
    "print(\"Val   set rows: {}\".format(val_df.shape[0]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 三、构建模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def read_image(file_name):\n",
    "    image = skimage.io.imread(IMAGE_PATH + file_name)\n",
    "    image = skimage.transform.resize(image, (IMAGE_WIDTH, IMAGE_HEIGHT, 1), mode='reflect')\n",
    "    return image[:,:,:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def categories_encoder(dataset, var='character'):\n",
    "    X = np.stack(dataset['file'].apply(read_image))\n",
    "    y = pd.get_dummies(dataset[var], drop_first=False) #get_dummies是利用pandas实现one hot encode的方式。\n",
    "    return X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(9600, 8)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, y_train = categories_encoder(train_df)\n",
    "X_val,   y_val   = categories_encoder(val_df)\n",
    "X_test,  y_test  = categories_encoder(test_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((9600, 64, 64, 1), (9600, 15))"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape,y_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 64, 64, 16)        160       \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 64, 64, 16)        2320      \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 32, 32, 16)        0         \n",
      "_________________________________________________________________\n",
      "dropout (Dropout)            (None, 32, 32, 16)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_2 (Conv2D)            (None, 32, 32, 16)        2320      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 16, 16, 16)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_3 (Conv2D)            (None, 16, 16, 16)        2320      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_2 (MaxPooling2 (None, 8, 8, 16)          0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 1024)              0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 15)                15375     \n",
      "=================================================================\n",
      "Total params: 22,495\n",
      "Trainable params: 22,495\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "\n",
    "model = tf.keras.Sequential([\n",
    "    tf.keras.layers.Conv2D(filters=16,kernel_size=(3,3),padding=\"same\",activation=\"relu\",input_shape=[64, 64, 1]),\n",
    "    tf.keras.layers.Conv2D(filters=16,kernel_size=(3,3),padding=\"same\",activation=\"relu\"),\n",
    "\n",
    "    tf.keras.layers.MaxPooling2D((2,2)),\n",
    "    tf.keras.layers.Dropout(0.5),\n",
    "    tf.keras.layers.Conv2D(filters=16,kernel_size=(3,3),padding=\"same\",activation=\"relu\"),\n",
    "    tf.keras.layers.MaxPooling2D((2,2)),\n",
    "    tf.keras.layers.Conv2D(filters=16,kernel_size=(3,3),padding=\"same\",activation=\"relu\"),\n",
    "    tf.keras.layers.MaxPooling2D((2,2)),\n",
    "    tf.keras.layers.Flatten(),\n",
    "    tf.keras.layers.Dense(15, activation=\"softmax\")\n",
    "])\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 四、编译"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "model.compile(optimizer=\"adam\",\n",
    "                loss='categorical_crossentropy',\n",
    "                metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(9600, 15)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 五、训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.keras.callbacks import ModelCheckpoint, Callback, EarlyStopping, ReduceLROnPlateau, LearningRateScheduler\n",
    "\n",
    "# 设置动态学习率\n",
    "annealer = LearningRateScheduler(lambda x: 1e-3 * 0.99 ** (x+NO_EPOCHS))\n",
    "\n",
    "# 设置早停\n",
    "earlystopper = EarlyStopping(monitor='loss', patience=PATIENCE, verbose=VERBOSE)\n",
    "\n",
    "# \n",
    "checkpointer = ModelCheckpoint('best_model.h5',\n",
    "                                monitor='val_accuracy',\n",
    "                                verbose=VERBOSE,\n",
    "                                save_best_only=True,\n",
    "                                save_weights_only=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/50\n",
      "300/300 [==============================] - 4s 5ms/step - loss: 1.8074 - accuracy: 0.4356 - val_loss: 1.2356 - val_accuracy: 0.6237\n",
      "\n",
      "Epoch 00001: val_accuracy improved from -inf to 0.62375, saving model to best_model.h5\n",
      "Epoch 2/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.9848 - accuracy: 0.6914 - val_loss: 0.7914 - val_accuracy: 0.7508\n",
      "\n",
      "Epoch 00002: val_accuracy improved from 0.62375 to 0.75083, saving model to best_model.h5\n",
      "Epoch 3/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.6645 - accuracy: 0.7898 - val_loss: 0.5913 - val_accuracy: 0.8117\n",
      "\n",
      "Epoch 00003: val_accuracy improved from 0.75083 to 0.81167, saving model to best_model.h5\n",
      "Epoch 4/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.4919 - accuracy: 0.8407 - val_loss: 0.4744 - val_accuracy: 0.8462\n",
      "\n",
      "Epoch 00004: val_accuracy improved from 0.81167 to 0.84625, saving model to best_model.h5\n",
      "Epoch 5/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.3897 - accuracy: 0.8749 - val_loss: 0.3602 - val_accuracy: 0.8875\n",
      "\n",
      "Epoch 00005: val_accuracy improved from 0.84625 to 0.88750, saving model to best_model.h5\n",
      "Epoch 6/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.3211 - accuracy: 0.8953 - val_loss: 0.3080 - val_accuracy: 0.8979\n",
      "\n",
      "Epoch 00006: val_accuracy improved from 0.88750 to 0.89792, saving model to best_model.h5\n",
      "Epoch 7/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.2747 - accuracy: 0.9100 - val_loss: 0.2686 - val_accuracy: 0.9137\n",
      "\n",
      "Epoch 00007: val_accuracy improved from 0.89792 to 0.91375, saving model to best_model.h5\n",
      "Epoch 8/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.2426 - accuracy: 0.9193 - val_loss: 0.2786 - val_accuracy: 0.9092\n",
      "\n",
      "Epoch 00008: val_accuracy did not improve from 0.91375\n",
      "Epoch 9/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.2073 - accuracy: 0.9333 - val_loss: 0.2309 - val_accuracy: 0.9221\n",
      "\n",
      "Epoch 00009: val_accuracy improved from 0.91375 to 0.92208, saving model to best_model.h5\n",
      "Epoch 10/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1852 - accuracy: 0.9379 - val_loss: 0.2169 - val_accuracy: 0.9283\n",
      "\n",
      "Epoch 00010: val_accuracy improved from 0.92208 to 0.92833, saving model to best_model.h5\n",
      "Epoch 11/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1732 - accuracy: 0.9450 - val_loss: 0.2054 - val_accuracy: 0.9350\n",
      "\n",
      "Epoch 00011: val_accuracy improved from 0.92833 to 0.93500, saving model to best_model.h5\n",
      "Epoch 12/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1540 - accuracy: 0.9507 - val_loss: 0.2142 - val_accuracy: 0.9279\n",
      "\n",
      "Epoch 00012: val_accuracy did not improve from 0.93500\n",
      "Epoch 13/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1457 - accuracy: 0.9522 - val_loss: 0.1920 - val_accuracy: 0.9379\n",
      "\n",
      "Epoch 00013: val_accuracy improved from 0.93500 to 0.93792, saving model to best_model.h5\n",
      "Epoch 14/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1244 - accuracy: 0.9626 - val_loss: 0.1837 - val_accuracy: 0.9433\n",
      "\n",
      "Epoch 00014: val_accuracy improved from 0.93792 to 0.94333, saving model to best_model.h5\n",
      "Epoch 15/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1181 - accuracy: 0.9611 - val_loss: 0.1799 - val_accuracy: 0.9421\n",
      "\n",
      "Epoch 00015: val_accuracy did not improve from 0.94333\n",
      "Epoch 16/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1170 - accuracy: 0.9613 - val_loss: 0.1857 - val_accuracy: 0.9479\n",
      "\n",
      "Epoch 00016: val_accuracy improved from 0.94333 to 0.94792, saving model to best_model.h5\n",
      "Epoch 17/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1044 - accuracy: 0.9651 - val_loss: 0.1824 - val_accuracy: 0.9450\n",
      "\n",
      "Epoch 00017: val_accuracy did not improve from 0.94792\n",
      "Epoch 18/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0985 - accuracy: 0.9657 - val_loss: 0.1632 - val_accuracy: 0.9454\n",
      "\n",
      "Epoch 00018: val_accuracy did not improve from 0.94792\n",
      "Epoch 19/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.1004 - accuracy: 0.9655 - val_loss: 0.1960 - val_accuracy: 0.9483\n",
      "\n",
      "Epoch 00019: val_accuracy improved from 0.94792 to 0.94833, saving model to best_model.h5\n",
      "Epoch 20/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0814 - accuracy: 0.9740 - val_loss: 0.1841 - val_accuracy: 0.9429\n",
      "\n",
      "Epoch 00020: val_accuracy did not improve from 0.94833\n",
      "Epoch 21/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0807 - accuracy: 0.9746 - val_loss: 0.2037 - val_accuracy: 0.9438\n",
      "\n",
      "Epoch 00021: val_accuracy did not improve from 0.94833\n",
      "Epoch 22/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0832 - accuracy: 0.9723 - val_loss: 0.1546 - val_accuracy: 0.9600\n",
      "\n",
      "Epoch 00022: val_accuracy improved from 0.94833 to 0.96000, saving model to best_model.h5\n",
      "Epoch 23/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0756 - accuracy: 0.9756 - val_loss: 0.1612 - val_accuracy: 0.9504\n",
      "\n",
      "Epoch 00023: val_accuracy did not improve from 0.96000\n",
      "Epoch 24/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0653 - accuracy: 0.9789 - val_loss: 0.1584 - val_accuracy: 0.9550\n",
      "\n",
      "Epoch 00024: val_accuracy did not improve from 0.96000\n",
      "Epoch 25/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0610 - accuracy: 0.9787 - val_loss: 0.1917 - val_accuracy: 0.9496\n",
      "\n",
      "Epoch 00025: val_accuracy did not improve from 0.96000\n",
      "Epoch 26/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0691 - accuracy: 0.9773 - val_loss: 0.1671 - val_accuracy: 0.9600\n",
      "\n",
      "Epoch 00026: val_accuracy did not improve from 0.96000\n",
      "Epoch 27/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0539 - accuracy: 0.9832 - val_loss: 0.1782 - val_accuracy: 0.9513\n",
      "\n",
      "Epoch 00027: val_accuracy did not improve from 0.96000\n",
      "Epoch 28/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0621 - accuracy: 0.9793 - val_loss: 0.1631 - val_accuracy: 0.9596\n",
      "\n",
      "Epoch 00028: val_accuracy did not improve from 0.96000\n",
      "Epoch 29/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0521 - accuracy: 0.9815 - val_loss: 0.1497 - val_accuracy: 0.9613\n",
      "\n",
      "Epoch 00029: val_accuracy improved from 0.96000 to 0.96125, saving model to best_model.h5\n",
      "Epoch 30/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0506 - accuracy: 0.9830 - val_loss: 0.1517 - val_accuracy: 0.9638\n",
      "\n",
      "Epoch 00030: val_accuracy improved from 0.96125 to 0.96375, saving model to best_model.h5\n",
      "Epoch 31/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0458 - accuracy: 0.9857 - val_loss: 0.1672 - val_accuracy: 0.9592\n",
      "\n",
      "Epoch 00031: val_accuracy did not improve from 0.96375\n",
      "Epoch 32/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0434 - accuracy: 0.9867 - val_loss: 0.1591 - val_accuracy: 0.9608\n",
      "\n",
      "Epoch 00032: val_accuracy did not improve from 0.96375\n",
      "Epoch 33/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0435 - accuracy: 0.9857 - val_loss: 0.1670 - val_accuracy: 0.9625\n",
      "\n",
      "Epoch 00033: val_accuracy did not improve from 0.96375\n",
      "Epoch 34/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0405 - accuracy: 0.9865 - val_loss: 0.1756 - val_accuracy: 0.9600\n",
      "\n",
      "Epoch 00034: val_accuracy did not improve from 0.96375\n",
      "Epoch 35/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0406 - accuracy: 0.9853 - val_loss: 0.1495 - val_accuracy: 0.9621\n",
      "\n",
      "Epoch 00035: val_accuracy did not improve from 0.96375\n",
      "Epoch 36/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0416 - accuracy: 0.9853 - val_loss: 0.1564 - val_accuracy: 0.9638\n",
      "\n",
      "Epoch 00036: val_accuracy did not improve from 0.96375\n",
      "Epoch 37/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0400 - accuracy: 0.9864 - val_loss: 0.1747 - val_accuracy: 0.9625\n",
      "\n",
      "Epoch 00037: val_accuracy did not improve from 0.96375\n",
      "Epoch 38/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0399 - accuracy: 0.9864 - val_loss: 0.1730 - val_accuracy: 0.9604\n",
      "\n",
      "Epoch 00038: val_accuracy did not improve from 0.96375\n",
      "Epoch 39/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0359 - accuracy: 0.9876 - val_loss: 0.1554 - val_accuracy: 0.9621\n",
      "\n",
      "Epoch 00039: val_accuracy did not improve from 0.96375\n",
      "Epoch 40/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0354 - accuracy: 0.9878 - val_loss: 0.1592 - val_accuracy: 0.9592\n",
      "\n",
      "Epoch 00040: val_accuracy did not improve from 0.96375\n",
      "Epoch 41/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0318 - accuracy: 0.9896 - val_loss: 0.1791 - val_accuracy: 0.9663\n",
      "\n",
      "Epoch 00041: val_accuracy improved from 0.96375 to 0.96625, saving model to best_model.h5\n",
      "Epoch 42/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0298 - accuracy: 0.9893 - val_loss: 0.1727 - val_accuracy: 0.9583\n",
      "\n",
      "Epoch 00042: val_accuracy did not improve from 0.96625\n",
      "Epoch 43/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0328 - accuracy: 0.9884 - val_loss: 0.1709 - val_accuracy: 0.9650\n",
      "\n",
      "Epoch 00043: val_accuracy did not improve from 0.96625\n",
      "Epoch 44/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0323 - accuracy: 0.9906 - val_loss: 0.1508 - val_accuracy: 0.9683\n",
      "\n",
      "Epoch 00044: val_accuracy improved from 0.96625 to 0.96833, saving model to best_model.h5\n",
      "Epoch 45/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0273 - accuracy: 0.9906 - val_loss: 0.1349 - val_accuracy: 0.9679\n",
      "\n",
      "Epoch 00045: val_accuracy did not improve from 0.96833\n",
      "Epoch 46/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0287 - accuracy: 0.9900 - val_loss: 0.1653 - val_accuracy: 0.9638\n",
      "\n",
      "Epoch 00046: val_accuracy did not improve from 0.96833\n",
      "Epoch 47/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0243 - accuracy: 0.9924 - val_loss: 0.1612 - val_accuracy: 0.9646\n",
      "\n",
      "Epoch 00047: val_accuracy did not improve from 0.96833\n",
      "Epoch 48/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0262 - accuracy: 0.9911 - val_loss: 0.1613 - val_accuracy: 0.9642\n",
      "\n",
      "Epoch 00048: val_accuracy did not improve from 0.96833\n",
      "Epoch 49/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0244 - accuracy: 0.9920 - val_loss: 0.1448 - val_accuracy: 0.9658\n",
      "\n",
      "Epoch 00049: val_accuracy did not improve from 0.96833\n",
      "Epoch 50/50\n",
      "300/300 [==============================] - 1s 4ms/step - loss: 0.0287 - accuracy: 0.9908 - val_loss: 0.1575 - val_accuracy: 0.9679\n",
      "\n",
      "Epoch 00050: val_accuracy did not improve from 0.96833\n"
     ]
    }
   ],
   "source": [
    "train_model  = model.fit(X_train, y_train,\n",
    "                  batch_size=BATCH_SIZE,\n",
    "                  epochs=NO_EPOCHS,\n",
    "                  verbose=1,\n",
    "                  validation_data=(X_val, y_val),\n",
    "                  callbacks=[earlystopper, checkpointer, annealer])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 六、评估模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Accuracy与Loss图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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h5vSeJrkejfddBN//OMfj1j3jjvuaJjOuCmrV68G4KSTTgprf8eitLSUPn36sG/fPp3sQqkIEBHye2WQ38uOfbx8SwkHanwEgwZ/0DTcA6QkOklOcJGS4CQl0UVygpNyr5+t+6rYuq+Srfuq2FJcxbLN+6j124kjkhOcjOiZzshemQzrkUZOWiLZKYlkpSbQNSUBj9tJnT/I9pIqNu+tZPPeSr4srmTnAS8j8zKYNCyXMf27tlhtDgYNIrTfBCWqU4idRDhUEU7TirDqaG/+HHZ/2rb77D4Szv1dsz+eNm0ab731FkOGDGHRokVMn976q3OPNWltLhFuqyQY4L///S+1tbW8++67TJ06tc32q5RqvQSXgwlDclq93al9D529LBA0fFlcyaeFZXxaVMbawgP8/aPteH3BI7ZNTXRR4wsc0tPcKzOJ3PREnv5gO48v20paoosJQ3OYNCyXId3S2LovlDQXV7J5j03AUz0uRvRMJ79XBiN7ZZDfM4PeXZM0OVZhi5mssqFHWC+WU53AtGnTuP/++7n++ut5++23uf3226msrGTmzJl4vV769u3LvHnzWtxH4yrx/v37ueSSSwgEAhhjKCgoaHJ/v/jFL3j55ZcBePrpp1m0aFGT+6utrWX27Nns3LmTvLw85s2bxz333IPP52PZsmWUlZWxYMECunfv3mRsCxYs4IYbbmDBggVMnToVr9fL7NmzKSwsJDMzkxdeeAGHw3HEsrlz5zZUs+sr5LNnz6agoIAxY8awdu1aFi5c2OSxNfUa9913H8OGDeOyyy7jzjvvZOjQoVx66aXH98tTqpNyOoQh3dIY0i2Ni07NA+yIT0UHathXWUdpVR0llbWUVNWxr7KWlAQXg3LthYEDclJISbQpSVWtn/c272Pxxr0s2riX19cebNsQgd5dkhmUm8qEIdmU1fhYV1TOo+9uaahgpya6SE10keh2kOB0NNynJLrISUu0t9REctM95KQmkp7kIiXBRUqii5REJ0lupybSnUjsJMJebY1QEdJC5ba9jB07ltWrV1NYWEhycjJZWVls2rSJG264gcmTJzN9+nT27NlDt27dwtrfI488wte//nVuuukmpkyZAsCuXbuO2N+9997L0KFDAZtgNufRRx8lPz+f+fPnc+edd/LEE08AsHnzZpYsWcLcuXNZvHgxl19+eZPbf/DBByxb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\n",
      "text/plain": [
       "<Figure size 864x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "acc = train_model.history['accuracy']\n",
    "val_acc = train_model.history['val_accuracy']\n",
    "\n",
    "loss = train_model.history['loss']\n",
    "val_loss = train_model.history['val_loss']\n",
    "\n",
    "epochs_range = range(len(acc))\n",
    "\n",
    "plt.figure(figsize=(12, 4))\n",
    "plt.subplot(1, 2, 1)\n",
    "\n",
    "plt.plot(epochs_range, acc, label='Training Accuracy')\n",
    "plt.plot(epochs_range, val_acc, label='Validation Accuracy')\n",
    "plt.legend(loc='lower right')\n",
    "plt.title('Training and Validation Accuracy')\n",
    "\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.plot(epochs_range, loss, label='Training Loss')\n",
    "plt.plot(epochs_range, val_loss, label='Validation Loss')\n",
    "plt.legend(loc='upper right')\n",
    "plt.title('Training and Validation Loss')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 混淆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x504 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "import seaborn as sns\n",
    "import pandas as pd\n",
    "\n",
    "class_names = [\"零\",\"一\",\"二\",\"三\",\"四\",\"五\",\"六\",\"七\",\"八\",\"九\",\"十\",\"百\",\"千\",\"万\",\"亿\"]\n",
    "\n",
    "# 定义一个绘制混淆矩阵图的函数\n",
    "def plot_cm(labels, predictions):\n",
    "    \n",
    "    # 生成混淆矩阵\n",
    "    conf_numpy = confusion_matrix(labels, predictions)\n",
    "    # 将矩阵转化为 DataFrame\n",
    "    conf_df = pd.DataFrame(conf_numpy, index=class_names ,columns=class_names)  \n",
    "    \n",
    "    plt.figure(figsize=(8,7))\n",
    "    \n",
    "    sns.heatmap(conf_df, annot=True, fmt=\"d\", cmap=\"BuPu\")\n",
    "    \n",
    "    plt.title('混淆矩阵',fontsize=15)\n",
    "    plt.ylabel('真实值',fontsize=14)\n",
    "    plt.xlabel('预测值',fontsize=14)\n",
    "    \n",
    "predicted      = model.predict(X_test)\n",
    "test_predicted = np.argmax(predicted, axis=1)\n",
    "test_truth     = np.argmax(y_test.values, axis=1)\n",
    "# 绘制混淆矩阵\n",
    "plot_cm(test_truth,test_predicted)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 各项指标评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test loss: 0.13785076141357422\n",
      "Test accuracy: 0.9706666469573975\n"
     ]
    }
   ],
   "source": [
    "score = model.evaluate(X_test, y_test, verbose=0)\n",
    "print('Test loss:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           一       0.99      0.98      0.99       200\n",
      "           七       0.98      0.98      0.98       200\n",
      "           万       0.97      0.96      0.97       200\n",
      "           三       0.96      0.99      0.97       200\n",
      "           九       0.97      0.95      0.96       200\n",
      "           二       0.98      0.95      0.96       200\n",
      "           五       0.99      0.99      0.99       200\n",
      "           亿       0.97      0.98      0.97       200\n",
      "           八       0.99      1.00      1.00       200\n",
      "           六       0.96      0.98      0.97       200\n",
      "           十       0.89      0.97      0.93       200\n",
      "           千       0.98      0.88      0.92       200\n",
      "           四       0.98      0.99      0.98       200\n",
      "           百       0.96      0.94      0.95       200\n",
      "           零       0.99      1.00      1.00       200\n",
      "\n",
      "    accuracy                           0.97      3000\n",
      "   macro avg       0.97      0.97      0.97      3000\n",
      "weighted avg       0.97      0.97      0.97      3000\n",
      "\n",
      "Loss function: 0.13785076141357422, accuracy: 0.9706666469573975\n"
     ]
    }
   ],
   "source": [
    "from sklearn import metrics\n",
    "\n",
    "def test_accuracy_report(model):\n",
    "    predicted      = model.predict(X_test)\n",
    "    test_predicted = np.argmax(predicted, axis=1)\n",
    "    test_truth     = np.argmax(y_test.values, axis=1)\n",
    "    \n",
    "    print(metrics.classification_report(test_truth, test_predicted, target_names=y_test.columns)) \n",
    "    \n",
    "    test_res = model.evaluate(X_test, y_test.values, verbose=0)\n",
    "    print('Loss function: %s, accuracy:' % test_res[0], test_res[1])\n",
    "test_accuracy_report(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 七、同系列作品\n",
    "\n",
    "🚀 **深度学习新人必看：[《小白入门深度学习》](https://blog.csdn.net/qq_38251616/category_11188161.html)**\n",
    "\n",
    "1. [小白入门深度学习 | 第一篇：配置深度学习环境](https://mtyjkh.blog.csdn.net/article/details/118575238)\n",
    "2. [小白入门深度学习 | 第二篇：编译器的使用-Jupyter Notebook](https://mtyjkh.blog.csdn.net/article/details/118814364)\n",
    "3. [小白入门深度学习 | 第三篇：深度学习初体验](https://mtyjkh.blog.csdn.net/article/details/119081309)\n",
    "4. [小白入门深度学习 | 第四篇：配置PyTorch环境](https://mtyjkh.blog.csdn.net/article/details/119969393)\n",
    "\n",
    "🚀 往期精彩-卷积神经网络篇：\n",
    "\n",
    "1. [深度学习100例-卷积神经网络（CNN）实现mnist手写数字识别 | 第1天](https://mtyjkh.blog.csdn.net/article/details/116920825) \n",
    "2. [深度学习100例-卷积神经网络（CNN）彩色图片分类 | 第2天](https://mtyjkh.blog.csdn.net/article/details/116978213)\n",
    "3. [深度学习100例-卷积神经网络（CNN）服装图像分类 | 第3天](https://mtyjkh.blog.csdn.net/article/details/116992196)\n",
    "4. [深度学习100例-卷积神经网络（CNN）花朵识别 | 第4天](https://mtyjkh.blog.csdn.net/article/details/117079919)\n",
    "5. [深度学习100例-卷积神经网络（CNN）天气识别 | 第5天](https://mtyjkh.blog.csdn.net/article/details/117186183)\n",
    "6. [深度学习100例-卷积神经网络（VGG-16）识别海贼王草帽一伙 | 第6天](https://mtyjkh.blog.csdn.net/article/details/117331631)\n",
    "7. [深度学习100例-卷积神经网络（VGG-19）识别灵笼中的人物 | 第7天](https://mtyjkh.blog.csdn.net/article/details/117395797)\n",
    "8. [深度学习100例-卷积神经网络（ResNet-50）鸟类识别 | 第8天](https://mtyjkh.blog.csdn.net/article/details/117587326)\n",
    "9. [深度学习100例-卷积神经网络（AlexNet）手把手教学 | 第11天](https://mtyjkh.blog.csdn.net/article/details/117986183)\n",
    "10. [深度学习100例-卷积神经网络（CNN）识别验证码 | 第12天](https://mtyjkh.blog.csdn.net/article/details/118211253)\n",
    "11. [深度学习100例-卷积神经网络（Inception V3）识别手语 | 第13天](https://mtyjkh.blog.csdn.net/article/details/118310170)\n",
    "12. [深度学习100例-卷积神经网络（Inception-ResNet-v2）识别交通标志 | 第14天](https://mtyjkh.blog.csdn.net/article/details/118389790)\n",
    "13. [深度学习100例-卷积神经网络（CNN）实现车牌识别 | 第15天](https://mtyjkh.blog.csdn.net/article/details/118422302)\n",
    "14. [深度学习100例-卷积神经网络（CNN）识别神奇宝贝小智一伙 | 第16天](https://mtyjkh.blog.csdn.net/article/details/118631541)\n",
    "15. [深度学习100例-卷积神经网络（CNN）注意力检测 | 第17天](https://mtyjkh.blog.csdn.net/article/details/118938811)\n",
    "16. [深度学习100例-卷积神经网络（VGG-16）猫狗识别 | 第21天](https://mtyjkh.blog.csdn.net/article/details/119531838)\n",
    "17. [深度学习100例-卷积神经网络（LeNet-5）深度学习里的“Hello Word” | 第22天](https://mtyjkh.blog.csdn.net/article/details/119700804)\n",
    "18. [深度学习100例-卷积神经网络（CNN）3D医疗影像识别 | 第23天](https://mtyjkh.blog.csdn.net/article/details/119899570)\n",
    "19. [深度学习100例 | 第24天-卷积神经网络（Xception）：动物识别](https://blog.csdn.net/qq_38251616/article/details/120073717)\n",
    "\n",
    "🚀 往期精彩-循环神经网络篇：\n",
    "\n",
    "1. [深度学习100例-循环神经网络（RNN）实现股票预测 | 第9天](https://mtyjkh.blog.csdn.net/article/details/117752046)\n",
    "2. [深度学习100例-循环神经网络（LSTM）实现股票预测 | 第10天](https://mtyjkh.blog.csdn.net/article/details/117907074)\n",
    "\n",
    "🚀 往期精彩-生成对抗网络篇：\n",
    "\n",
    "1. [深度学习100例-生成对抗网络（GAN）手写数字生成 | 第18天](https://mtyjkh.blog.csdn.net/article/details/118995896)\n",
    "2. [深度学习100例-生成对抗网络（DCGAN）手写数字生成 | 第19天](https://mtyjkh.blog.csdn.net/article/details/119133575)\n",
    "3. [深度学习100例-生成对抗网络（DCGAN）生成动漫小姐姐 | 第20天](https://mtyjkh.blog.csdn.net/article/details/119182578)\n",
    "\n",
    "\n",
    "**🚀 本文选自专栏：[《深度学习100例》](https://blog.csdn.net/qq_38251616/category_11068756.html)**\n",
    "\n",
    "**💖先赞后看，再收藏，养成好习惯！💖**\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8rc1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
